Python wrapper for the Intercom API.

Overview

python-intercom

PyPI Version PyPI Downloads Travis CI Build Coverage Status

Not officially supported

Please note that this is NOT an official Intercom SDK. The third party that maintained it reached out to us to note that they were unable to host it any longer. As it was being used by some Intercom customers we offered to host it to allow the current Python community to continue to use it. However, it will not be maintained or updated by Intercom. It is a community maintained SDK. Please see here for the official list of Intercom SDKs

Python bindings for the Intercom API (https://developers.intercom.com/intercom-api-reference).

API Documentation.

Package Documentation.

Upgrading information

Version 3 of python-intercom is not backwards compatible with previous versions.

Version 3 moves away from a global setup approach to the use of an Intercom Client.

Installation

pip install python-intercom

Basic Usage

Configure your client

from intercom.client import Client
intercom = Client(personal_access_token='my_personal_access_token')

Note that certain resources will require an extended scope access token : Setting up Personal Access Tokens

Resources

Resources this API supports:

https://api.intercom.io/users
https://api.intercom.io/contacts
https://api.intercom.io/companies
https://api.intercom.io/counts
https://api.intercom.io/tags
https://api.intercom.io/notes
https://api.intercom.io/segments
https://api.intercom.io/events
https://api.intercom.io/conversations
https://api.intercom.io/messages
https://api.intercom.io/subscriptions
https://api.intercom.io/jobs
https://api.intercom.io/bulk

Examples

Users

# Find user by email
user = intercom.users.find(email="[email protected]")
# Find user by user_id
user = intercom.users.find(user_id="1")
# Find user by id
user = intercom.users.find(id="1")
# Create a user
user = intercom.users.create(email="[email protected]", name="Bob Smith")
# Delete a user
user = intercom.users.find(id="1")
deleted_user = intercom.users.delete(user)
# Update custom_attributes for a user
user.custom_attributes["average_monthly_spend"] = 1234.56
intercom.users.save(user)
# Perform incrementing
user.increment('karma')
intercom.users.save(user)
# Iterate over all users
for user in intercom.users.all():
    ...

Admins

# Iterate over all admins
for admin in intercom.admins.all():
    ...

Companies

# Add a user to one or more companies
user = intercom.users.find(email='[email protected]')
user.companies = [
    {'company_id': 6, 'name': 'Intercom'},
    {'company_id': 9, 'name': 'Test Company'}
]
intercom.users.save(user)
# You can also pass custom attributes within a company as you do this
user.companies = [
    {
        'id': 6,
        'name': 'Intercom',
        'custom_attributes': {
            'referral_source': 'Google'
        }
    }
]
intercom.users.save(user)
# Find a company by company_id
company = intercom.companies.find(company_id='44')
# Find a company by name
company = intercom.companies.find(name='Some company')
# Find a company by id
company = intercom.companies.find(id='41e66f0313708347cb0000d0')
# Update a company
company.name = 'Updated company name'
intercom.companies.save(company)
# Iterate over all companies
for company in intercom.companies.all():
    ...
# Get a list of users in a company
intercom.companies.users(company.id)

Tags

# Tag users
tag = intercom.tags.tag(name='blue', users=[{'email': '[email protected]'}])
# Untag users
intercom.tags.untag(name='blue', users=[{'user_id': '42ea2f1b93891f6a99000427'}])
# Iterate over all tags
for tag in intercom.tags.all():
    ...
# Tag companies
tag = intercom.tags.tag(name='blue', companies=[{'id': '42ea2f1b93891f6a99000427'}])

Segments

# Find a segment
segment = intercom.segments.find(id=segment_id)
# Iterate over all segments
for segment in intercom.segments.all():
    ...

Notes

# Find a note by id
note = intercom.notes.find(id=note)
# Create a note for a user
note = intercom.notes.create(
    body="<p>Text for the note</p>",
    email='[email protected]')
# Iterate over all notes for a user via their email address
for note in intercom.notes.find_all(email='[email protected]'):
    ...
# Iterate over all notes for a user via their user_id
for note in intercom.notes.find_all(user_id='123'):
    ...

Conversations

# FINDING CONVERSATIONS FOR AN ADMIN
# Iterate over all conversations (open and closed) assigned to an admin
for convo in intercom.conversations.find_all(type='admin', id='7'):
    ...
# Iterate over all open conversations assigned to an admin
for convo in intercom.conversations.find_all(type='admin', id=7, open=True):
    ...
# Iterate over closed conversations assigned to an admin
for convo intercom.conversations.find_all(type='admin', id=7, open=False):
    ...
# Iterate over closed conversations for assigned an admin, before a certain
# moment in time
for convo in intercom.conversations.find_all(
        type='admin', id= 7, open= False, before=1374844930):
    ...

# FINDING CONVERSATIONS FOR A USER
# Iterate over all conversations (read + unread, correct) with a user based on
# the users email
for convo in intercom.onversations.find_all(email='[email protected]',type='user'):
    ...
# Iterate over through all conversations (read + unread) with a user based on
# the users email
for convo in intercom.conversations.find_all(
        email='[email protected]', type='user', unread=False):
    ...
# Iterate over all unread conversations with a user based on the users email
for convo in intercom.conversations.find_all(
        email='[email protected]', type='user', unread=true):
    ...

# FINDING A SINGLE CONVERSATION
conversation = intercom.conversations.find(id='1')

# INTERACTING WITH THE PARTS OF A CONVERSATION
# Getting the subject of a part (only applies to email-based conversations)
conversation.rendered_message.subject
# Get the part_type of the first part
conversation.conversation_parts[0].part_type
# Get the body of the second part
conversation.conversation_parts[1].body

# REPLYING TO CONVERSATIONS
# User (identified by email) replies with a comment
intercom.conversations.reply(
    type='user', email='[email protected]',
    message_type='comment', body='foo')
# Admin (identified by email) replies with a comment
intercom.conversations.reply(
    type='admin', email='[email protected]',
    message_type='comment', body='bar')
# User (identified by email) replies with a comment and attachment
intercom.conversations.reply(id=conversation.id, type='user', email='[email protected]', message_type='comment', body='foo', attachment_urls=['http://www.example.com/attachment.jpg'])

# Open
intercom.conversations.open(id=conversation.id, admin_id='123')

# Close
intercom.conversations.close(id=conversation.id, admin_id='123')

# Assign
intercom.conversations.assign(id=conversation.id, admin_id='123', assignee_id='124')

# Reply and Open
intercom.conversations.reply(id=conversation.id, type='admin', admin_id='123', message_type='open', body='bar')

# Reply and Close
intercom.conversations.reply(id=conversation.id, type='admin', admin_id='123', message_type='close', body='bar')

# ASSIGNING CONVERSATIONS TO ADMINS
intercom.conversations.reply(id=conversation.id, type='admin', assignee_id=assignee_admin.id, admin_id=admin.id, message_type='assignment')

# MARKING A CONVERSATION AS READ
intercom.conversations.mark_read(conversation.id)

Full loading of an embedded entity

# Given a conversation with a partial user, load the full user. This can be
# done for any entity
intercom.users.load(conversation.user)

Sending messages

# InApp message from admin to user
intercom.messages.create(**{
    "message_type": "inapp",
    "body": "What's up :)",
    "from": {
        "type": "admin",
        "id": "1234"
    },
    "to": {
        "type": "user",
        "id": "5678"
    }
})

# Email message from admin to user
intercom.messages.create(**{
    "message_type": "email",
    "subject": "Hey there",
    "body": "What's up :)",
    "template": "plain", # or "personal",
    "from": {
        "type": "admin",
        "id": "1234"
    },
    "to": {
        "type": "user",
        "id": "536e564f316c83104c000020"
    }
})

# Message from a user
intercom.messages.create(**{
    "from": {
        "type": "user",
        "id": "536e564f316c83104c000020"
    },
    "body": "halp"
})

# Message from admin to contact
intercom.messages.create(**{
    'body': 'How can I help :)',
    'from': {
        'type': 'admin',
        'id': '1234'
    },
    'to': {
        'type': 'contact',
        'id': '536e5643as316c83104c400671'
    }
})

# Message from a contact
intercom.messages.create(**{
    'from' => {
        'type': 'contact',
        'id': '536e5643as316c83104c400671'
    },
    'body': 'halp'
})

Events

import time

intercom.events.create(
    event_name='invited-friend',
    created_at=int(time.mktime(time.localtime())),
    email=user.email,
    metadata={
        'invitee_email': '[email protected]',
        'invite_code': 'ADDAFRIEND',
        'found_date': 12909364407
    }
)

# Retrieve event list for user with id:'123abc'
intercom.events.find_all(type='user', "intercom_user_id"="123abc)

Metadata Objects support a few simple types that Intercom can present on your behalf

current_user = intercom.users.find(id="1")

intercom.events.create(
    event_name="placed-order",
    email=current_user.email,
    created_at=1403001013,
    metadata={
        'order_date': time.mktime(time.localtime()),
        'stripe_invoice': 'inv_3434343434',
        'order_number': {
            'value': '3434-3434',
            'url': 'https://example.org/orders/3434-3434'
        },
        'price': {
            'currency': 'usd',
            'amount': 2999
        }
    }
)

The metadata key values in the example are treated as follows-

  • order_date: a Date (key ends with '_date').
  • stripe_invoice: The identifier of the Stripe invoice (has a 'stripe_invoice' key)
  • order_number: a Rich Link (value contains 'url' and 'value' keys)
  • price: An Amount in US Dollars (value contains 'amount' and 'currency' keys)

Contacts

Contacts represent logged out users of your application.

# Create a contact
contact = intercom.leads.create(email="[email protected]")

# Update a contact
contact.custom_attributes['foo'] = 'bar'
intercom.leads.save(contact)

# Find contacts by email
contacts = intercom.leads.find_all(email="[email protected]")

# Merge a contact into a user
user = intercom.users.find(id="1")
intercom.leads.convert(contact, user)

# Delete a contact
intercom.leads.delete(contact)

Counts

# App-wide counts
intercom.counts.for_app()

# Users in segment counts
intercom.counts.for_type(type='user', count='segment')

Subscriptions

Subscribe to events in Intercom to receive webhooks.

# create a subscription
intercom.subscriptions.create(url='http://example.com', topics=['user.created'])

# fetch a subscription
intercom.subscriptions.find(id='nsub_123456789')

# list subscriptions
intercom.subscriptions.all():
    ...

Errors

You do not need to deal with the HTTP response from an API call directly. If there is an unsuccessful response then an error that is a subclass of intercom.Error will be raised. If desired, you can get at the http_code of an Error via it's http_code method.

The list of different error subclasses are listed below. As they all inherit off IntercomError you can choose to except IntercomError or the more specific error subclass:

AuthenticationError
ServerError
ServiceUnavailableError
ServiceConnectionError
ResourceNotFound
BadGatewayError
BadRequestError
RateLimitExceeded
MultipleMatchingUsersError
HttpError
UnexpectedError

Rate Limiting

Calling your clients rate_limit_details returns a dict that contains details about your app's current rate limit.

intercom.rate_limit_details
# {'limit': 180, 'remaining': 179, 'reset_at': datetime.datetime(2014, 10, 07, 14, 58)}

Running the Tests

Unit tests:

nosetests tests/unit

Integration tests:

INTERCOM_PERSONAL_ACCESS_TOKEN=xxx nosetests tests/integration
Google Sheets Python API v4

pygsheets - Google Spreadsheets Python API v4 A simple, intuitive library for google sheets which gets your work done. Features: Open, create, delete

Nithin Murali 1.4k Jan 08, 2023
Python wrapper library for World Weather Online API

pywwo Python wrapper library for World Weather Online API using lxml.objectify How to use from pywwo import * setKey('your_key', 'free') w=LocalWeat

World Weather Online 20 Dec 19, 2022
An unofficial client library for Google Music.

gmusicapi: an unofficial API for Google Play Music gmusicapi allows control of Google Music with Python. from gmusicapi import Mobileclient api = Mob

Simon Weber 2.5k Dec 15, 2022
Replacement for the default Dark Sky Home Assistant integration using Pirate Weather

Pirate Weather Integrations This integration is designed to replace the default Dark Sky integration in Home Assistant with a slightly modified, but f

Alexander Rey 129 Jan 06, 2023
An automated tool that fetches information about your crypto stake and generates historical data in time.

Introduction Yield explorer is a WIP! I needed a tool that would show me historical data and performance of my staked crypto but was unable to find a

Sedat Can Yalçın 42 Nov 26, 2022
TheTimeMachine - Weaponizing WaybackUrls for Recon, BugBounties , OSINT, Sensitive Endpoints and what not

The Time Machine - Weaponizing WaybackUrls for Recon, BugBounties , OSINT, Sensi

Anmol K Sachan 112 Dec 29, 2022
A Simple Google Translate Bot By VndGroup ❤️ Made With Python

VndGroup Google Translator Heroku Deploy ❤️ Functions This Bot Can Translate 95 Languages We Can Set Custom Language Group Support Mandatory Vars [+]

Venuja Sadew 1 Oct 09, 2022
Discord bot written in discord.py

Orion Discord bot written in discord.py Installation Installation of code is supported for macOS only currently First open the terminal. If incase you

Zeus 3 May 19, 2022
UniHub API is my solution to bringing students and their universities closer

🎓 UniHub API UniHub API is my solution to bringing students and their universities closer... By joining UniHub, students will be able to join their r

Abdelbaki Boukerche 5 Nov 21, 2021
Open Source API and interchange format for editorial timeline information.

OpenTimelineIO is currently in Public Beta. That means that it may be missing some essential features and there are large changes planned. During this phase we actively encourage you to provide feedb

Pixar Animation Studios 1.2k Jan 01, 2023
An inline real-time media searching robot without any database.

MediaBuddy A Telegram Inline media searching robot without any database. About mediaBuddy is an inline media searching robot. If you have so many movi

Renjith Mangal 28 Oct 21, 2022
Telegram File Renamer Bot

RENAMER_BOT Telegram File Renamer Bot Configs TG_BOT_TOKEN - Get bot token from @BotFather API_ID - From my.telegram.org API_HASH - From my.telegram.o

Lntechnical 37 Dec 27, 2022
As Slack no longer provides an API to invite people, this is a Selenium Python script to do so

As Slack no longer provides an API to invite people, this is a Selenium Python script to do so

An async-ready Python wrapper around FerrisChat's API.

FerrisWheel An async-ready Python wrapper around FerrisChat's API. Installation Instructions Linux: $ python3.9 -m pip install -U ferriswheel Python 3

FerrisChat 8 Feb 08, 2022
trackbranch is a tool for developers that can be used to store collections of branches in the form of profiles.

trackbranch trackbranch is a tool for developers that can be used to store collections of branches in the form of profiles. This can be useful for sit

Kevin Morris 1 Oct 21, 2021
A compatability shim between Discord.py and Hikari.

Usage as a partial shim: import discord import hikari import hikari_shim dpy_bot = discord.Client(intents=discord.Intents.all(), enable_debug_events=

EXPLOSION 3 Dec 25, 2021
TON Miner from TON-Pool.com

TON-Pool Miner Miner from TON-Pool.com

21 Nov 18, 2022
Bot inspirado no Baidu Antivírus

Baidu Bot Bot inspirado no lendário Baidu Antivírus Informações O programa foi inteiramente feito em Python, sinta-se livre para fazer qualquer altera

Caio Eduardo de Albuquerque Magalhães 1 Dec 18, 2021
Shuffle and add items from jellyfin to mpd (use in tandem with jellyfin-mopidy and mpd-mopidy). Similar to ncmpcpp's "Add random" feature..

jellyshuf Essentially implements ncmpcpp's add random feature (default hotkey: `) through a script which grabs info from jellyfin api itself. jellyfin

Ethan Djeric 2 Dec 14, 2021
MSE5050/7050 Materials Informatics course at the University of Utah

MaterialsInformatics MSE5050/7050 Materials Informatics course at the University of Utah This github repo contains coursework content such as class sl

41 Dec 30, 2022