How to merge all vertices by distance and remove all inner faces?
First of all if you want to write your own basic scripts you should go to Edit -> Preferences -> Interface and enable "Python Tooltips". 

After that you will see pop-up hints with python references for certain buttons, menus and values commands every time you place a mouse cursor over them. Also you can press Ctrl+C (or Cmd+C on mac) when your cursor is over the button and it will copy the python command for that button to the buffer, so you can paste it in your script. 

Also you can open up the Info Window in Blender, many commands appear there right after executing and you can copy them from there. Also you can open Console Window in Blender and start typing in commands you know - and use an autocomplete option (shortcuts may be different but you can easily find it).

A little bit of theory before the script. Note that in most cases copying python commands from the buttons will give you a Blender operator starting with bpy.ops. It is not prohibited to use those operators in the scripts, but it is not very stable and may cause errors because all Blender operators rely on context (exact window, screen, area and region from which it is called). There are hints to override a context, here for example. But generally the more efficient way is to use direct access to blender data and change it directly without using the operators. Unfortunately direct editing of the mesh data with Blender API is pretty... let's call it strange and unpredictable (in my opinion). There is bmesh module which has been written specially for this purpose, but I'd say it is pretty complex especially if you are a beginner not recommended. Anyway, if you are not writing a very complex program, using bpy.ops is ok. 

According to your algorithm a script may look like this:

import bpy

merge_threshold = 0.05 # here you can define Merge By Distance threshold

if bpy.context.mode != 'OBJECT':
    bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
# This is to make sure that there is an active object in the scene:
#----------------------------------------------
if not bpy.context.active_object.hide_viewport:
    for object in bpy.context.scene.objects:
        if not object.hide_viewport:
            bpy.context.view_layer.objects.active = object
            break
#----------------------------------------------
bpy.ops.object.join()
bpy.ops.object.convert(target='MESH') # Here I've added an option which will
                                      # apply all modifiers by converting object
                                      # to mesh
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles(threshold = merge_threshold)
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.mesh.select_mode(type = 'FACE')
bpy.ops.mesh.select_interior_faces()
bpy.ops.mesh.delete(type='FACE')
bpy.ops.object.mode_set(mode='OBJECT')


UPD. Info Window and Python Console Window can be opened as any other window in Blender:

Toggle System Console in Windows opens up a system console where you can find detailed information about errors, results of your print() functions, etc.