QR Code for Printing Badge

Dear all,

we are using Indico to manage a conference with approximately 1000 participants. To speed up the check-in process, we ask ourselves if it is possible to use Indico (and perhaps the CheckIn app) to print badges - so to say: The participant shows his QR Code on the ticket, and a label printer directly prints a badge … could only find an old discussion here (Print-on-Registration plugin). However, we don’t have access to the respective Indico server … therefore: Does anybody know another solution? Perhaps a polling of the participant list via HTTP API (which does not seem to work, or am I wrong?) to check for new registrants and a perhaps self-programmed python-app fetching the user data and printing the tickets?

Thank you for you help, best
Christian

You’d need to develop something custom. Either using the Indico API or as an Indico plugin. The latter won’t work since you do not have server access, so polling registrants and their checkin state is the only option.

You could also use a fork of the checkin app (I strongly suggest to not use the legacy one but wait until 3.3 is properly released and you can use the new one) to make some API call to a custom app that triggers the printing of the badge - that way you avoid the polling.

Just to expand on this, here’s the relevant part of the code which interacts with Indico to fetch the participant data in the new Checkin app (to be released with 3.3):

Dear all,

thank you for the hints and help. I had a look at the different codes, trying to understand the process. I still have two questions:

  1. Using a fork of the new checkin-app: To really use the app, it seems - at least from the documentation - that I need access to the Indico server (which I don’t have). On the first page of the GitHub repository, there’s the sentence:

If you are self-hosting the app, you will also need to modify the Check-in app URL and the authorization callback URL in your Indico instance.

That means I will not be able to interact with the Indico server as I cannot modify the authorization callback?

2.) Using the old check-in-app, I was able to access the registrants list by creating an API Token (starting with indp…) which I use in Postman as Bearer Authorization (with the URL out of the file “indicoApiService.js”). This works well (although it seems I cannot get all fields listed in the registration and have to manually combine the obtained data with a manually created CSV). However, I cannot checkin a participant. I used the “PATCH” method with the URL I also use to get the data for one registrant, as body I set a JSON-String “{checked_in: true}” - but the checkin state of the participant stays the same.

So sorry to bother you again … but am I right with 1) (can’t use the new app) and why I can’t check-in somebody with 2)?

Thank you very much,
Christian

Indeed if you don’t have access to the Indico server or can’t ask someone who does, the Check-in app route is not gonna work.

As for using the API, there are two endpoints that you can use that are also used by the old Check-in app (we’re adding more endpoints in 3.3):

/api/events/<int:event_id>/registrants - This will list all registrations for the given event. In the old API there is no way to ask for a specific registration form, it simply returns all registrations from all forms.

/api/events/<int:event_id>/registrants/<int:registrant_id> - This returns data about a single registration.

If you search the Indico codebase for RHAPIRegistrant(s) you’ll find the implementation.

I’m not sure why you’re not able to change the check-in status. What is the response status code? Is it 400 by any chance? Normally, you should send a PATCH to the second endpoint with this body (and include the bearer token)

{
  "checked_in": true
}

Thank you! Cool that new endpoints will be available - at the moment, I need (for badge printing) the Name, Affiliation and the Registrant ID - in an exported CSV, I don’t have the ID while in the JSON delivered by the API, I don’t have the affiliation - therefore, I need to combine both.

Concerning the checkin status: I attach a screenshot out of Postman which also shows the headers sent.

Method: PATCH
Body: As written in your post
Authorization: Bearer indp …
Content-Type: Application/json

Perhaps I am missing something important … the response status code is 200, but with no change of the checkin status … Do I need to transmit the checkin_secret somewhere?

Thank you again,
Christian

Is it possible that the registrations don’t have an affiliation filled in? When I request /api/events/<int:event_id>/registrants I can see the affiliation in the output, under personal data.

The PATCH request is strange, the fact that you get a 200 should mean that the status was updated… I’ll look into it further

Thank you! Figured out - at least - why the affiliation isn’t shown. I haven’t used the “Affiliation”-Field that was provided, but created a new one - as I needed it in another section of the registration form. Therefore, I have one hidden “Affiliation”-Field under “Personal Data” and one additional one created manually. Thus, no affiliation is shown in the JSON. Perhaps I will alter my form as the affiliation cannot be moved to another section …

Yes, if you want the affiliation to show up, you’ll have to use the default affiliation field :slight_smile:

Ok I’m stumped… I don’t know why the PATCH request is not working for you :confused:
Could you share the response headers as well? What is the Indico version that you are using?

You could also try sending some nonsense (e.g. {"foo": "bar"}) in the PATCH body just to ensure that you correctly get an error when doing that. I don’t see why your request would be handled by different code but best to rule out any oddities.

The indico server I am using shows a strange behaviour … no matter what I do in the body (valid JSON, not valid JSON, foo:bar or something else), the registrant is returned in the body that I asked for by the API endpoint … but without any change if inserting “checked-in”:true in the body.

I am attaching a file of the response headers, however, I think (if the basics of what I am doing are correct) that I will try to implement it in Python and have a look there … don’t know if Postman is doing something strange as I can’t look under the hood :slight_smile:

The Indico server I am using is version 3.2.9 …

Last question: Anybody of you working with Postman and got that working?

Big thank you for your help! Will keep you posted after trying with python…

Dear all,

I tried to access the Indico API with Python now - generated the code using postman. However, whatever I do, it throws me an error “415 - Unsupported Media Typ”. Don’t know if it is good that - at least - there is an error now, but could you confirm this code should work?

import requests

url = "http://XXXXXXX.de/api/events/167/registrants/1234"


headers = {
  'Authorization': 'Bearer indp_iXXXXXXXXXXXXXXXXXXXXXXXXXXVT9',
  'Content-Type': 'application/json' 
}

body= "\"checked_in\":True"

response = requests.patch(url, headers=headers,data = body )

#print(response.text)
print(response.status_code)

Also cURL doesn’t seem to work, but giving me a “Bad request”:

curl --location --request PATCH 'http://XXXXXXX.de/api/events/167/registrants/1234' \
--header 'Content-Type: text/plain' \
--header 'Authorization: Bearer indp_iXXXXXXXXXXXXXXXXXXXXXXXXXT9' \
--data '{"checked_in":True}'

Am I missing something obvious?? :slight_smile:

Thank you again, best
Christian

Your JSON body in Python is invalid. Pass json={'checked_in': True} to requests and it will automatically turn it into JSON w/ the correct contente-type header.

And your curl command is wrong because you sent text/plain instead of application/json, so the JSON payload Indico sees is considered empty.

Tried several things - in the checkin app, you are using this code:

const body = JSON.stringify({checked_in: value});
    const res = await fetch(checkinUrl, {
      headers: { 'Authorization': `Bearer ${server.token}`, 'Content-Type': 'application/json' },
      method: 'PATCH',
      body,
    });

Therefore, I thought a string for the body (JSON.stringify) with Content Type application/json is correct. However, I also tried this (Python):


headers = {
  'Authorization': 'Bearer indp_ihXXXXXXXX5VT9',
  'Content-Type': 'application/json' 
}

response = requests.patch(url, headers=headers,json={'checked_in': True} )

Also returning 415

… and by the way, also deleting the ‘Content-Type’ attribute in headers does the same …

Yes, a string would be fine of course, but a valid JSON payload would have been body = '{"checked_in":true}' (it’s an object so you need the curly braces around it!).

You are right, missed the curly braces … but also tried it

  • json library and “json.dumps” to create the string
  • using the string as below
  • using ‘json=’ directly in the request instead of using a string for the data variable

Now:

headers = {
  'Authorization': 'Bearer indp_iXXXXXXXXXXXXXT9',
  'Content-Type': 'application/json' 
}

body= '{"checked_in":True}'

response = requests.patch(url, headers=headers, data=body )

The response status code is still 415 …

ah sorry, you need lowercase true when sending it as a string

Got it working! Thank you!

The problem was not the string, the JSON (tried so many variants), but that in Postman, the cURL and also in the python code, I used an URL starting with “http://” … using the same URL but with “https://” works … don’t know why, and why it returns “200” when using http. But the “s” made the difference.

Thank you for your help!!!

Best
Christian

duh! it redirects from http to https, and clients switch to a GET request in case of such a redirect.

i think in indico (or even in flask) there’s code to make this an error in case of a POST request because it’s almost always not what one expects, but of course it’s done on the webserver level which will happily redirect :wink:

1 Like