Expose the timeline through an API?

Shopify Partner
5 0 0

+1

0 Likes
Shopify Partner
28 0 2

+1

Steve Conroy. Booster Apps (https://apps.shopify.com/partners/booster-apps)
0 Likes
New Member
2 0 1

+1

1 Like
Tourist
4 0 7

+1

0 Likes
Shopify Partner
14 0 3

+1 really need

 

This has now been requested for two years. Fair to say that it would be good with a response from an admin on what the status of this is.

0 Likes
Shopify Partner
14 0 3

Alright, so as this thread is successfully being ignored by Shopify I went ahead and researched this deeper.

There are two ways of achieving this:

 

Solution #1:

Shopify has in Beta a new API called GraphQL. The documentation is really sub par, but it is possible to get the timeline comments using this: https://help.shopify.com/api/graphql-admin-api/reference/object/commentevent

Below is a working Python Script for doing this:

`

import requests
import re
import sys
import json

#Getting the date out of an individual comment
def getdate(s):
    pattern = r'(?<=createdAt"\:").+?(?=\"})'
    date = re.findall(pattern, s)
    return date[0]

#Getting the message out of an individual comment
def getmessage(s):
    pattern = r'(?<=message"\:").+?(?=\"\,\"createdAt")'
    message = re.findall(pattern, s)
    return message[0]

def readsettings():
#Reading AUTH token (API Password in Shopify) and the name of your shop from settings.txt. First line should contain key, while the second one should contain name
    f = open("get_order_comments_settings.txt", "r")
    lines = f.read().splitlines()
    url = "https://" + lines[1] + ".myshopify.com/admin/api/graphql.json"
    auth = lines[0]
    #print("auth: " + auth + "'\n url: " + url)
    return (url, auth)

#Main function
def gql():
    
#You should use the script with 1 command-line argument (order id), you can get this order ID by going to the url of your order and copying the last part
    if len(sys.argv) < 1 or len(sys.argv) >2:
        print("Invalid usage of the command! \n Correct usage: python bot.py <order_id>")
        return
#Getting all the order events
    query = r'{ order(id: "gid://shopify/Product/' + sys.argv[1] + '"){events(first: 100){edges{node{__typename message createdAt  }}}}}'
    
#Getting settings
    (url, api_token) = readsettings()

#Commented out hard-coded values
    #url = r'https://tester35353.myshopify.com/admin/api/graphql.json'
    #api_token = "51d157d4ff8ef92bdd65e7011b52c14e"
    
    headers = {'X-Shopify-Access-Token': api_token, 'Content-Type' : "application/graphql"}

#posting the request to GraphiQL Shopify API
    r = requests.post(url=url, data=query, headers=headers)

#searching for the right events from the response
    pattern = r'typename":"CommentEvent".+?(?=\{)'
    
    found  = re.findall(pattern, r.text)

#basic error handling, should be expanded on/changed if you need to feed the output to another script
    if len(found) < 1:
        print("No matches, details: \n" + r.text)
    dictionary = {}
    index = 0
    
#forming a dictionary to dump into json
    for i in found:
        dictionary["Comment " + str(index)] = (getmessage(i), getdate(i))
        index+=1
        #print("message: " + getmessage(i))
        #print("date: " + getdate(i))

#printing out the result to STDOUT
    print(json.dumps(dictionary))
    #print("order id: " + sys.argv[1])

if __name__ == '__main__':
    gql()
`

 

Solution #2:

You can just crawl the shopify web front end and perform a login. Below is an UNVERIFIED solution to this. I paid a developer to do this before I created the solution above, and as such I haven't tested the code. Use at your own risk:

`

#sudo apt-get install python-pip
#sudo pip install selenium

from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import sys 
import json
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

vendor_name='jaipur09'         ########## Enter your vendor name                     
dict={}
order_id=sys.argv[1]
email = sys.argv[2]
password = sys.argv[3]


options = webdriver.ChromeOptions()
options.add_argument("headless")
browser=webdriver.Chrome(executable_path="/home/mukul/Downloads/chromedriver",chrome_options=options)

#login page
browser.get("https://"+vendor_name+".myshopify.com/admin/auth/login") 
time.sleep(3)
print("Logging In")
emailObj = browser.find_element_by_xpath('//*[@id="Login"]')
passwordObj = browser.find_element_by_xpath('//*[@id="Password"]')
emailObj.send_keys(email)
passwordObj.send_keys(password)
login_attempt = browser.find_element_by_xpath('//*[@id="LoginSubmit"]')
login_attempt.submit()

element = WebDriverWait(browser, 100).until(EC.presence_of_element_located((By.XPATH, '//*[@id="AppFrameNav"]/nav/div[2]/div/ul[1]/li[2]/a/span')))
print("LogIn done")

#order_id page
browser.get('https://'+vendor_name+'.myshopify.com/admin/draft_orders/'+str(order_id))
time.sleep(3)
print("Scraping data")

#extracting comments and time
comments=browser.find_elements(By.CLASS_NAME,'timeline__comment-body')
times=browser.find_elements(By.CLASS_NAME,'timeline__time-link') 

for num in range(0,len(comments)):
    comment=comments[num]
    time=times[num]
    dict['comment'+str(num+1)]=comment.text
    dict['time'+str(num+1)]=time.text

print (json.dumps(dict))

`

 

 

I have solution #1 in production and it's working like a charm.

 

0 Likes
Shopify Partner
14 0 3

... and I'm back to this thread. Because now, I need to post to the timeline. And, I can't find any solution. Seems GraphiQL api doesn't support that either.

 

Please shopify?

1 Like
Shopify Partner
1843 171 543

In GraphQL for events.

query {
  order(id: "gid://shopify/Order/790544056435") {
    events(first:5, sortKey: CREATED_AT, reverse: true) {
      pageInfo {
        hasNextPage
        hasPreviousPage
      }
      edges {
        node {
          __typename
          id
          message
          createdAt
          appTitle
          attributeToApp
          attributeToUser
          criticalAlert
        }
        cursor
      }
    }
  }
}

More basic in REST

GET /admin/events.json?filter=Order

or for specific Order

GET /admin/orders/915566133363/events.json

There are some requests or queries that are buggy and some event types that don't seem to be retrievable via APIs, but it is there. Am I missing something?

I turn coffee in to code - since 1998
1 Like
New Member
1 0 1

+1 

 

Badly needed endpoint.

1 Like
Shopify Partner
2 0 0

+ 1

0 Likes